package com.example.aidocengine.service.impl;

import com.example.aidocengine.common.exception.BusinessException;
import com.example.aidocengine.common.result.ResultCode;
import com.example.aidocengine.common.utils.FileUtils;
import com.example.aidocengine.mapper.PrimaryDeviceTerminologyMapper;
import com.example.aidocengine.mapper.SecondaryDeviceTerminologyMapper;
import com.example.aidocengine.mapper.TemplatePlaceholderRulesMapper;
import com.example.aidocengine.mapper.DeviceStateTransitionMapper;
import com.example.aidocengine.pojo.entity.PrimaryDeviceTerminology;
import com.example.aidocengine.pojo.entity.SecondaryDeviceTerminology;
import com.example.aidocengine.pojo.entity.TemplatePlaceholderRules;
import com.example.aidocengine.pojo.entity.DeviceStateTransition;
import com.example.aidocengine.service.TerminologyImportService;
import com.example.aidocengine.validator.AdvancedPrimaryDeviceValidator;
import com.example.aidocengine.validator.SecondaryDeviceValidator;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class TerminologyImportServiceImpl implements TerminologyImportService {

    @Autowired
    private SecondaryDeviceTerminologyMapper secondaryDeviceTerminologyMapper;
    
    @Autowired
    private PrimaryDeviceTerminologyMapper primaryDeviceTerminologyMapper;
    
    @Autowired
    private TemplatePlaceholderRulesMapper templatePlaceholderRulesMapper;
    
    @Autowired
    private DeviceStateTransitionMapper deviceStateTransitionMapper;
    
    @Autowired
    private SecondaryDeviceValidator secondaryDeviceValidator;
    
    @Autowired
    private AdvancedPrimaryDeviceValidator advancedPrimaryDeviceValidator;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importTerminologyLibrary(MultipartFile file) {
        log.info("开始导入术语库文件：{}", file.getOriginalFilename());
        
        if (!FileUtils.isValidFile(file)) {
            throw new BusinessException(ResultCode.FILE_UPLOAD_ERROR.getCode(), "无效的文件格式或文件为空");
        }

        if (!FileUtils.isExcelFile(file.getOriginalFilename())) {
            throw new BusinessException(ResultCode.FILE_UPLOAD_ERROR.getCode(), "只支持Excel文件格式(.xlsx, .xls)");
        }

        try (Workbook workbook = new XSSFWorkbook(file.getInputStream())) {
            
            // 1. 导入二次设备术语表
            importSecondaryDeviceTerminology(workbook);
            
            // 2. 导入一次设备术语模板表
            importPrimaryDeviceTemplate(workbook);
            
            // 3. 初始化占位符规则
            initializePlaceholderRules();
            
            // 4. 初始化状态转换规则
            initializeStateTransitionRules();
            
            log.info("术语库导入完成");
            
        } catch (IOException e) {
            log.error("解析术语库Excel文件失败：", e);
            throw new BusinessException(ResultCode.DOCUMENT_PARSE_ERROR.getCode(), "解析术语库文件失败：" + e.getMessage());
        }
    }

    /**
     * 导入二次设备术语表
     */
    private void importSecondaryDeviceTerminology(Workbook workbook) {
        Sheet sheet = workbook.getSheet("程序化术语模板（二次设备）");
        if (sheet == null) {
            log.warn("未找到'程序化术语模板（二次设备）'工作表");
            return;
        }

        List<SecondaryDeviceTerminology> terminologyList = new ArrayList<>();
        
        // 从第二行开始读取数据
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i);
            if (row == null) continue;
            
            try {
                // 假设第一列是关键字，第二列是描述
                Cell keywordCell = row.getCell(0);
                Cell descriptionCell = row.getCell(1);
                
                if (keywordCell != null) {
                    String keyword = getCellValueAsString(keywordCell);
                    if (StringUtils.hasText(keyword)) {
                        SecondaryDeviceTerminology terminology = new SecondaryDeviceTerminology();
                        terminology.setKeyword(keyword.trim());
                        terminology.setRemark(descriptionCell != null ? getCellValueAsString(descriptionCell) : "");
                        terminology.setStatus(1);
                        terminology.setCreatedTime(LocalDateTime.now());
                        terminology.setUpdatedTime(LocalDateTime.now());
                        terminologyList.add(terminology);
                    }
                }
                
            } catch (Exception e) {
                log.warn("解析二次设备术语第{}行失败：{}", i + 1, e.getMessage());
            }
        }
        
        if (!terminologyList.isEmpty()) {
            // 先清空现有数据（可选）
            // secondaryDeviceTerminologyMapper.delete(new QueryWrapper<>());
            
            // 批量插入（需要实现批量插入方法）
            for (SecondaryDeviceTerminology terminology : terminologyList) {
                secondaryDeviceTerminologyMapper.insert(terminology);
            }
            log.info("导入二次设备术语{}条", terminologyList.size());
        }
    }

    /**
     * 导入一次设备术语模板表
     */
    private void importPrimaryDeviceTemplate(Workbook workbook) {
        Sheet sheet = workbook.getSheet("程序化术语模板（一次设备）");
        if (sheet == null) {
            log.warn("未找到'程序化术语模板（一次设备）'工作表");
            return;
        }

        List<PrimaryDeviceTerminology> templateList = new ArrayList<>();
        
        // 根据截图分析的表格结构解析
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i);
            if (row == null) continue;
            
            try {
                // 根据截图：列0-设备类型，列1-编写原则，列2-示例，列3-特殊说明，列4-校核不通过的提示语
                Cell deviceTypeCell = row.getCell(0);
                Cell writingPrincipleCell = row.getCell(1);
                Cell exampleCell = row.getCell(2);
                Cell specialNotesCell = row.getCell(3);
                Cell validationMessageCell = row.getCell(4);
                
                if (deviceTypeCell != null && writingPrincipleCell != null) {
                    String deviceCategory = getCellValueAsString(deviceTypeCell);
                    String templatePattern = getCellValueAsString(writingPrincipleCell);
                    
                    if (StringUtils.hasText(deviceCategory) && StringUtils.hasText(templatePattern)) {
                        PrimaryDeviceTerminology template = new PrimaryDeviceTerminology();
                        template.setDeviceType(deviceCategory.trim());
                        template.setWritingPrinciple(templatePattern.trim());
                        template.setTypicalExample(exampleCell != null ? getCellValueAsString(exampleCell) : "");
                        template.setRemark(specialNotesCell != null ? getCellValueAsString(specialNotesCell) : "");
                        
                        // 设置层级结构相关字段
                        template.setParentId(null);
                        template.setIsTemplate(1);
                        template.setDisplayOrder(0);
                        template.setIsDeleted(0);
                        template.setStatus(1);
                        template.setCreatedTime(LocalDateTime.now());
                        template.setUpdatedTime(LocalDateTime.now());
                        
                        templateList.add(template);
                    }
                }
                
            } catch (Exception e) {
                log.warn("解析一次设备模板第{}行失败：{}", i + 1, e.getMessage());
            }
        }
        
        if (!templateList.isEmpty()) {
            primaryDeviceTerminologyMapper.insertBatch(templateList);
            log.info("导入一次设备模板{}条", templateList.size());
        }
    }

    /**
     * 初始化占位符规则
     */
    private void initializePlaceholderRules() {
        List<TemplatePlaceholderRules> rules = new ArrayList<>();
        
        // 设备名称类占位符
        addPlaceholderRule(rules, "（XX主变）", "DEVICE_NAME", "[\\u4e00-\\u9fa5\\w]+", "主变设备名称占位符");
        addPlaceholderRule(rules, "（XX线路）", "DEVICE_NAME", "[\\u4e00-\\u9fa5\\w]+", "线路设备名称占位符");
        addPlaceholderRule(rules, "（XX母线）", "DEVICE_NAME", "[\\u4e00-\\u9fa5\\w]+", "母线设备名称占位符");
        addPlaceholderRule(rules, "（XX开关）", "DEVICE_NAME", "[\\u4e00-\\u9fa5\\w]+", "开关设备名称占位符");
        
        // 状态转换类占位符
        addPlaceholderRule(rules, "（初始状态）", "STATE_TRANSITION", "(冷备用|运行|停止|试验位置|工作位置|断开|闭合)", "初始状态占位符");
        addPlaceholderRule(rules, "（目标状态）", "STATE_TRANSITION", "(冷备用|运行|停止|试验位置|工作位置|断开|闭合)", "目标状态占位符");
        
        // 电压等级类占位符
        addPlaceholderRule(rules, "（电压等级+母线编号）", "VOLTAGE_LEVEL", "[0-9]+kV[#\\w]*[0-9]*母线", "电压等级母线编号组合");
        
        // 批量插入规则
        for (TemplatePlaceholderRules rule : rules) {
            templatePlaceholderRulesMapper.insert(rule);
        }
        
        log.info("初始化占位符规则{}条", rules.size());
    }

    private void addPlaceholderRule(List<TemplatePlaceholderRules> rules, String placeholder, 
                                   String replacementType, String validationRule, String description) {
        TemplatePlaceholderRules rule = new TemplatePlaceholderRules();
        rule.setPlaceholder(placeholder);
        rule.setReplacementType(replacementType);
        rule.setValidationRule(validationRule);
        rule.setDescription(description);
        rule.setStatus(1);
        rule.setCreatedTime(LocalDateTime.now());
        rule.setUpdatedTime(LocalDateTime.now());
        rules.add(rule);
    }

    /**
     * 初始化状态转换规则
     */
    private void initializeStateTransitionRules() {
        List<DeviceStateTransition> transitions = new ArrayList<>();
        
        // 主变状态转换
        addStateTransition(transitions, "主变", "投入", "冷备用", "运行", "退出");
        addStateTransition(transitions, "主变", "退出", "运行", "冷备用", "投入");
        
        // 线路状态转换
        addStateTransition(transitions, "线路", "合上", "断开", "闭合", "断开");
        addStateTransition(transitions, "线路", "断开", "闭合", "断开", "合上");
        
        // 母线状态转换
        addStateTransition(transitions, "母线", "投入", "停止", "运行", "退出");
        addStateTransition(transitions, "母线", "退出", "运行", "停止", "投入");
        
        // 开关状态转换
        addStateTransition(transitions, "开关", "合闸", "断开", "闭合", "分闸");
        addStateTransition(transitions, "开关", "分闸", "闭合", "断开", "合闸");
        
        // 小车状态转换
        addStateTransition(transitions, "开关小车", "推至工作位置", "试验位置", "工作位置", "拉至试验位置");
        addStateTransition(transitions, "开关小车", "拉至试验位置", "工作位置", "试验位置", "推至工作位置");
        
        // 批量插入状态转换规则
        for (DeviceStateTransition transition : transitions) {
            deviceStateTransitionMapper.insert(transition);
        }
        
        log.info("初始化状态转换规则{}条", transitions.size());
    }

    private void addStateTransition(List<DeviceStateTransition> transitions, String deviceCategory, 
                                   String actionKeyword, String initialState, String targetState, 
                                   String reverseAction) {
        DeviceStateTransition transition = new DeviceStateTransition();
        transition.setDeviceCategory(deviceCategory);
        transition.setActionKeyword(actionKeyword);
        transition.setInitialState(initialState);
        transition.setTargetState(targetState);
        transition.setReverseAction(reverseAction);
        transition.setStatus(1);
        transition.setCreatedTime(LocalDateTime.now());
        transition.setUpdatedTime(LocalDateTime.now());
        transitions.add(transition);
    }

    @Override
    public void refreshTerminologyCache() {
        try {
            // 刷新二次设备校验器缓存
            secondaryDeviceValidator.refreshTerminologyCache();
            
            // 刷新高级一次设备校验器缓存
            advancedPrimaryDeviceValidator.refreshCache();
            
            log.info("术语缓存刷新完成");
        } catch (Exception e) {
            log.error("刷新术语缓存失败", e);
            throw new BusinessException(ResultCode.ERROR.getCode(), "刷新术语缓存失败：" + e.getMessage());
        }
    }

    @Override
    public List<SecondaryDeviceTerminology> getSecondaryTerms() {
        log.info("获取二次设备术语列表");
        return secondaryDeviceTerminologyMapper.selectAllActive();
    }

    @Override
    public List<PrimaryDeviceTerminology> getPrimaryTerms() {
        log.info("获取一次设备术语列表");
        return primaryDeviceTerminologyMapper.selectAllActive();
    }
    
    @Override
    public List<PrimaryDeviceTerminology> getPrimaryTermsHierarchy() {
        log.info("获取一次设备术语层级结构列表");
        return primaryDeviceTerminologyMapper.selectHierarchyData();
    }
    
    @Override
    public List<PrimaryDeviceTerminology> getDeviceTypes() {
        log.info("获取设备类型列表");
        return primaryDeviceTerminologyMapper.selectDeviceTypes();
    }
    
    @Override
    public List<PrimaryDeviceTerminology> getPrinciplesByParentId(Long parentId) {
        log.info("根据父ID获取编写原则列表，父ID：{}", parentId);
        return primaryDeviceTerminologyMapper.selectPrinciplesByParentId(parentId);
    }
    
    @Override
    public List<PrimaryDeviceTerminology> getDeletedPrimaryTerms() {
        log.info("获取标记删除的一次设备术语列表");
        return primaryDeviceTerminologyMapper.selectDeletedData();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SecondaryDeviceTerminology saveSecondaryTerm(SecondaryDeviceTerminology term) {
        log.info("保存二次设备术语：{}", term.getKeyword());
        if (term.getId() == null) {
            term.setCreatedTime(LocalDateTime.now());
            term.setUpdatedTime(LocalDateTime.now());
            term.setStatus(1);
            secondaryDeviceTerminologyMapper.insert(term);
        } else {
            term.setUpdatedTime(LocalDateTime.now());
            secondaryDeviceTerminologyMapper.updateById(term);
        }
        return term;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PrimaryDeviceTerminology savePrimaryTerm(PrimaryDeviceTerminology term) {
        log.info("保存一次设备术语：{}", term.getDeviceType());
        if (term.getId() == null) {
            term.setCreatedTime(LocalDateTime.now());
            term.setUpdatedTime(LocalDateTime.now());
            term.setStatus(1);
            primaryDeviceTerminologyMapper.insert(term);
        } else {
            term.setUpdatedTime(LocalDateTime.now());
            primaryDeviceTerminologyMapper.updateById(term);
        }
        return term;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSecondaryTerm(Long id) {
        log.info("删除二次设备术语ID：{}", id);
        secondaryDeviceTerminologyMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePrimaryTerm(Long id) {
        log.info("删除一次设备术语ID：{}", id);
        primaryDeviceTerminologyMapper.deleteById(id);
    }

    /**
     * 获取单元格值并转为字符串
     */
    private String getCellValueAsString(Cell cell) {
        if (cell == null) {
            return "";
        }
        
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    double numericValue = cell.getNumericCellValue();
                    if (numericValue == Math.floor(numericValue)) {
                        return String.valueOf((long) numericValue);
                    } else {
                        return String.valueOf(numericValue);
                    }
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
    }
}